import gugga.collections.HashTable;
import gugga.common.IEventDispatcher;
import gugga.utils.DebugUtils;
import gugga.utils.DoLaterUtil;

/**
 * @author Todor Kolev
 */
class gugga.events.EventDispatcher implements IEventDispatcher 
{
	private static var mEventDispatcher : EventDispatcher;
	
	private var mBroadcasters : HashTable;
				
	public function dispatchEventLater(aEventObject : Object) : Void 
	{
		DoLaterUtil.doLater(this, dispatchEvent, [aEventObject], 1);
	}

	public function dispatchEvent(aEventObject : Object) : Void 
	{
		var eventType : String = aEventObject["type"];
		mBroadcasters[eventType].broadcastMessage("handler", aEventObject);
	}

	public function addEventListener(aEventName:String, aHandler) : Void 
	{	
		if(!mBroadcasters)
		{
			mBroadcasters = new HashTable();
		}
		
		if(!mBroadcasters[aEventName])
		{
			mBroadcasters[aEventName] = new Object();
			AsBroadcaster.initialize(mBroadcasters[aEventName]);
		}
		
		var handlerWrapper : Object = { handler: aHandler };
		aHandler.handlerWrapper = handlerWrapper;
		
		mBroadcasters[aEventName].addListener(handlerWrapper);
	}

	public function removeEventListener(aEventName:String, aHandler) : Void 
	{
		var handlerWrapper : Function = aHandler.handlerWrapper;
		handlerWrapper.handler = null;
		
		mBroadcasters[aEventName].removeListener(handlerWrapper);
	}
	
	private function removeAllEventListeners() : Void
	{
		delete mBroadcasters;
	}

	public static function initialize(object:Object):Void
	{
		if (!mEventDispatcher)
		{
			mEventDispatcher = new EventDispatcher();
		}
		
		object.addEventListener = mEventDispatcher.addEventListener;
		object.removeEventListener = mEventDispatcher.removeEventListener;
		object.dispatchEvent = mEventDispatcher.dispatchEvent;
		object.dispatchEventLater = mEventDispatcher.dispatchEventLater;
	}
}